<template>
  <!-- 录制控制按钮 -->
  <div class="controls-container">
    <div class="mode-toggle">
      <button
        class="mode-btn"
        :class="{ active: isVideoMode }"
        @click="imChatStore.toggleMode(true)"
        :disabled="recordStatus != RecorderStatus.READY"
      >
        <i class="fas fa-video"></i> 视频
      </button>
      <button
        class="mode-btn"
        :class="{ active: !isVideoMode }"
        @click="imChatStore.toggleMode(false)"
        :disabled="recordStatus != RecorderStatus.READY"
      >
        <i class="fas fa-microphone"></i> 音频
      </button>
    </div>

    <div class="control-buttons">
      <!--     :disabled="recordStatus != RecorderStatus.COMPLETE" -->
      <button
        class="control-btn delete-btn"
        :disabled="recordedChunks.length <= 0"
        @click="onDeleteRecording"
      >
        <i class="fas fa-trash"></i>
        <span>删除</span>
      </button>

      <button
        class="control-btn primary-btn"
        :class="{
          start: recordStatus == RecorderStatus.READY,
          pause: recordStatus == RecorderStatus.RECORDING,
          resume: recordStatus == RecorderStatus.PAUSE
        }"
        @click="onToggleRecording"
      >
        <i class="fas" :class="recordingIcon"></i>
        <span>{{ recordingActionText }}{{ recordStatus }}</span>
      </button>
      <!--  :disabled="recordStatus == RecorderStatus.READY" -->
      <button
        class="control-btn save-btn"
        :disabled="recordedChunks.length <= 0"
        @click="onSaveRecording"
      >
        <i class="fas fa-download"></i>
        <span>保存{{ recordedChunks.length }}</span>
      </button>
      <button class="control-btn delete-btn" @click="onCloseRecording">
        <i class="fas fa-trash"></i>
        <span>结束</span>
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * navigator.mediaDevices.getUserMedia 获取硬件设备（麦克风 / 摄像头）的媒体流
 * new MediaRecorder 创建媒体录制对象 将媒体流编码并录制为可保存的文件
 */
import { RecorderStatus } from '@renderer/types/enums/recoder.enum'
import { downloadBlob } from '@renderer/utils'
import { useImChatStore } from '@renderer/store'
const imChatStore = useImChatStore()
const isVideoMode = computed(() => imChatStore.isVideoMode)
const recordStatus = computed(() => imChatStore.recordStatus)
// 录制按钮图标
const recordingIcon = computed(() => {
  if (recordStatus.value == RecorderStatus.READY) return 'fa-circle'
  if (recordStatus.value == RecorderStatus.RECORDING) return 'fa-pause'
  if (recordStatus.value == RecorderStatus.PAUSE) return 'fa-play'
  return 'fa-circle'
})

// 录制按钮文本
const recordingActionText = computed(() => {
  if (recordStatus.value == RecorderStatus.READY) return '开始'
  if (recordStatus.value == RecorderStatus.RECORDING) return '暂停'
  if (recordStatus.value == RecorderStatus.PAUSE) return '继续'
  return '开始'
})
// 录制相关变量
const mediaStream = ref<MediaStream | undefined>(undefined) // 媒体流 用途：录制视频
const mediaRecorder = ref<MediaRecorder>() // 媒体录制器 用途：录制视频
const recordedChunks = ref([]) as any // 录制的一些片段
const mediaBlob = ref<Blob>() // 存储最终的媒体blob
//-----------------一、媒体流(浏览器媒体)----------------
watch(
  () => mediaStream.value,
  () => {
    imChatStore.setMediaStream(mediaStream.value)
  }
)
// 初始化媒体流
const initMediaStream = async () => {
  try {
    // 先停止可能存在的旧流
    if (mediaStream.value) {
      stopMediaStream()
    }
    const constraints = isVideoMode.value
      ? {
          video: { width: { ideal: 1280 }, height: { ideal: 720 } },
          audio: true
        }
      : { video: false, audio: true } // 音频模式及配置信息

    mediaStream.value = await navigator.mediaDevices.getUserMedia(constraints) // 获取媒体流

    return true
  } catch (error) {
    console.error('无法访问媒体设备:', error)
    ElMessage.error('访问设备失败: ${error.message}`')
    return false
  }
}

// 3-停止媒体流
const stopMediaStream = () => {
  if (!mediaStream.value) return
  // 停止媒体流 mediaStream.value.getTracks()// 获取所有媒体轨道
  mediaStream.value.getTracks().forEach((track) => {
    track.stop()
  })
  mediaStream.value = undefined
}

// -----------------按钮及操作-------------------
// 切换录制 开始/暂停
const onToggleRecording = async () => {
  // 媒体流未初始化
  if (!mediaStream.value) {
    const success = await initMediaStream()
    if (!success) return
  }
  if (recordStatus.value == RecorderStatus.READY) {
    // 1. 录制状态为未开始状态
    startRecording()
  } else if (recordStatus.value == RecorderStatus.RECORDING) {
    // 2. 录制状态为开始状态
    pauseRecording()
  } else if (recordStatus.value == RecorderStatus.PAUSE) {
    // 3. 录制状态为暂停状态
    resumeRecording()
  }
}
// 删除录制内容
const onDeleteRecording = () => {
  stopRecording()
  resetRecording()
  ElMessage.success('已删除录制内容')
}
// 保存录制
const onSaveRecording = () => {
  if (!mediaBlob.value) {
    // 如果没有现成的blob，尝试从chunks创建
    if (recordedChunks.value.length === 0) {
      ElMessage.error('没有可保存的内容')
      return
    }
    const mimeType = isVideoMode.value ? 'video/webm' : 'audio/webm'
    mediaBlob.value = new Blob(recordedChunks.value, { type: mimeType })
  }

  try {
    // 生成带时间戳的文件名
    const timestamp = new Date().toISOString().replace(/:/g, '-').slice(0, 19)
    const fileName = `${isVideoMode.value ? 'video' : 'audio'}-recording-${timestamp}.webm`
    downloadBlob(mediaBlob.value, fileName, () => {
      resetRecording()
      ElMessage.success('录制内容已成功保存')
    })
  } catch (error: any) {
    console.error('保存失败:', error)
    ElMessage.error('保存失败:' + error.message)
  }
}
// 结束录制
const onCloseRecording = () => {
  stopRecording() // 停止录制
  stopMediaStream() // 停止媒体流不在唤起媒体流
}
//------------------媒体录制器-------------------
// 1-开始录制
const startRecording = () => {
  // 确保有媒体流
  if (!mediaStream.value) return
  // 确保清除之前的录制数据
  recordedChunks.value = []
  mediaBlob.value = undefined
  try {
    // 1.根据模式设置合适的MIME类型
    const mimeType = isVideoMode.value ? 'video/webm;codecs=vp9,opus' : 'audio/webm;codecs=opus'
    // 2.检查浏览器支持的格式
    if (!MediaRecorder.isTypeSupported(mimeType)) {
      console.warn(`不支持 ${mimeType} 格式，使用默认格式`)
      mediaRecorder.value = new MediaRecorder(mediaStream.value)
    } else {
      mediaRecorder.value = new MediaRecorder(mediaStream.value, { mimeType })
    }
    // 3.开始录制
    mediaRecorder.value.start()
    imChatStore.setRecordStatus(RecorderStatus.RECORDING)
    // 3-1. 处理录制数据   ondataavailable 回调该事件函数表示存在有效数据了，通过回调事件函数参数的 data 属性可以获取到数据
    mediaRecorder.value.ondataavailable = (e) => {
      console.log('收到录制数据:', e.data.size, '字节', '---')

      if (e.data.size > 0) {
        recordedChunks.value.push(e.data)
      }
    }

    mediaRecorder.value.onerror = (e) => {
      console.error('录制过程中发生错误:', e)
    }
    // 4. 处理录制结束时
    mediaRecorder.value.onstop = () => {
      // 创建完整的媒体blob
      const finalMimeType = isVideoMode.value ? 'video/webm' : 'audio/webm'
      mediaBlob.value = new Blob(recordedChunks.value, { type: finalMimeType })
      // imChatStore.setRecordStatus(RecorderStatus.COMPLETE)
    }
    console.log('开始录制，MediaRecorder状态:', mediaRecorder.value.state)

    ElMessage.success('开始录制...')
  } catch (error) {
    console.error('初始化录制器失败:', error)
  }
}
// 2-暂停录制
const pauseRecording = () => {
  if (mediaRecorder.value && recordStatus.value === RecorderStatus.RECORDING) {
    mediaRecorder.value.pause() //暂停
    imChatStore.setRecordStatus(RecorderStatus.PAUSE)
    ElMessage.success('录制已暂停')
  }
}
// 3-继续录制
const resumeRecording = () => {
  if (mediaRecorder.value && recordStatus.value === RecorderStatus.PAUSE) {
    mediaRecorder.value.resume() // 继续录制
    imChatStore.setRecordStatus(RecorderStatus.RECORDING)
    ElMessage.success('继续录制')
  }
}
// 4-停止录制（内部使用）
const stopRecording = () => {
  if (mediaRecorder.value && recordStatus.value !== RecorderStatus.READY) {
    mediaRecorder.value.stop()
    imChatStore.setRecordStatus(RecorderStatus.READY)
    ElMessage.success('录制已停止')
  }
}
// 重置录制状态
const resetRecording = () => {
  stopMediaStream()
  recordedChunks.value = []
  mediaBlob.value = undefined
  imChatStore.setRecordStatus(RecorderStatus.READY)
}
// 组件卸载时清理
onUnmounted(() => {
  onCloseRecording()
})
defineExpose({ onCloseRecording })
</script>

<style lang="scss" scoped>
.controls-container {
  .mode-toggle {
    display: flex;
    justify-content: center;
    gap: 12px;
    margin-bottom: 24px;

    .mode-btn {
      padding: 8px 16px;
      border: none;
      border-radius: 20px;
      background-color: #e0e0e0;
      color: #666;
      font-size: 14px;
      font-weight: 500;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      gap: 6px;

      &.active {
        background-color: #3498db;
        color: white;
        box-shadow: 0 2px 8px rgba(52, 152, 219, 0.4);
      }

      &:hover:not(.active):not(:disabled) {
        background-color: #d0d0d0;
      }

      &:disabled {
        opacity: 0.7;
        cursor: not-allowed;
      }
    }
  }

  .control-buttons {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;

    .control-btn {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      border: none;
      border-radius: 50%;
      cursor: pointer;
      transition: all 0.3s ease;
      padding: 12px;
      color: white;
      font-weight: 500;
      font-size: 12px;
      gap: 6px;

      i {
        font-size: 20px;
      }

      &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        transform: none;
        box-shadow: none;
      }
    }

    .delete-btn {
      background-color: #e74c3c;

      &:hover:not(:disabled) {
        background-color: #c0392b;
        transform: scale(1.05);
        box-shadow: 0 4px 12px rgba(231, 76, 60, 0.3);
      }
    }

    .primary-btn {
      width: 70px;
      height: 70px;

      &.start {
        background-color: #e74c3c;

        &:hover:not(:disabled) {
          background-color: #c0392b;
          transform: scale(1.05);
          box-shadow: 0 4px 12px rgba(231, 76, 60, 0.3);
        }
      }

      &.pause {
        background-color: #f39c12;

        &:hover:not(:disabled) {
          background-color: #d35400;
          transform: scale(1.05);
          box-shadow: 0 4px 12px rgba(243, 156, 18, 0.3);
        }
      }

      &.resume {
        background-color: #2ecc71;

        &:hover:not(:disabled) {
          background-color: #27ae60;
          transform: scale(1.05);
          box-shadow: 0 4px 12px rgba(46, 204, 113, 0.3);
        }
      }
    }

    .save-btn {
      background-color: #3498db;

      &:hover:not(:disabled) {
        background-color: #2980b9;
        transform: scale(1.05);
        box-shadow: 0 4px 12px rgba(52, 152, 219, 0.3);
      }
    }
  }
}
</style>
